package com.doraro.coal.config.shiro;

import com.doraro.coal.moudle.user.model.entity.Organize;
import com.doraro.coal.moudle.user.model.entity.Role;
import com.doraro.coal.moudle.user.model.entity.User;
import com.doraro.coal.moudle.user.service.IOrganizeService;
import com.doraro.coal.moudle.user.service.IRoleService;
import com.doraro.coal.moudle.user.service.IUserService;
import com.doraro.coal.utils.ShiroUtils;
import com.doraro.coal.vo.UserDto;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Set;

@Component
public class UserRealm extends AuthorizingRealm {
    @Autowired
    private IUserService userService;
    @Autowired
    private IRoleService roleService;
    @Autowired
    private IOrganizeService organizeService;

    /**
     * 授权(验证权限时调用) @RequirePerssion时调用
     *
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        final UserDto userDto = (UserDto) principals.getPrimaryPrincipal();
        final SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addRole(userDto.getRole().getRoleName());
        info.setStringPermissions(userDto.getPerms());
        return info;
    }

    /**
     * 登录时调用
     *
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //获取账号密码
        UsernamePasswordToken t = (UsernamePasswordToken) token;
        String userName= token.getPrincipal().toString();
        String password= new String( t.getPassword());

        User user = userService.lambdaQuery().eq(User::getUsername, userName).one();
        if (user == null) {
            throw new UnknownAccountException("用户账号或密码错误");
        }
        String dbPassword=user.getPassword();
        String sha256 = ShiroUtils.sha256(password, user.getSalt());

        if(null==dbPassword || !dbPassword.equals(sha256)) {
            throw new UnknownAccountException("用户账号或密码错误");
        }
        if (user.getStatus() == 1 || user.getStatus() == 2){
            final Role role = roleService.lambdaQuery().eq(Role::getRoleId, user.getRoleId()).one();
            final Organize organize = organizeService.lambdaQuery().eq(Organize::getId, user.getOrgId()).one();
            Set<String> perms = roleService.getPermsByUserId(user.getUserId());
            final UserDto userDto = new UserDto(user);
            userDto.setOrganize(organize);
            userDto.setRole(role);
            userDto.setPerms(perms);
            return new SimpleAuthenticationInfo(userDto,password,getName());
        }
        throw new DisabledAccountException("账号被禁用或冻结，请联系管理员");
    }
}
